package com.vids.controller;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.json.JSONUtil;
import com.fasterxml.jackson.annotation.JsonFilter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.vids.constant.Urlconstant;
import com.vids.constant.VIIDRespEnum;
import com.vids.model.entity.User;
import com.vids.model.entity.VIIDServer;
import com.vids.model.param.SubscribeRequestObject;
import com.vids.model.response.ResponseStatus;
import com.vids.utils.BeanUtilss;
import com.vids.utils.DegistUtils;
import com.vids.utils.QueryUtils;
import com.vids.utils.RestTemplateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.*;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.DefaultResponseErrorHandler;
import org.springframework.web.client.RestTemplate;

//import com.vids.utils.RestTemplateUtils.ResponseStatusRequestObject;
import org.apache.commons.codec.digest.DigestUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

/**
 * 处理订阅消息、取消订阅消息
 */
@Slf4j
@RestController
@RequestMapping("/ViidServer")
public class SubscribeController {

    @PostMapping("/subscribe/{id}")
    public Object sendSubscribeMsg(@PathVariable Integer id) throws Exception {
        //需要传入viid 或者 IP/port/ user/ password
        //VIIDServer viidServer
        log.info("viid=" + id);

        ResponseStatus status = new ResponseStatus("/VIID/Subscribes", VIIDRespEnum.OK.getCode(), new Date());
        String url = "http://11.32.32.11:31666" + "/VIID/Subscribes";

        SubscribeRequestObject subscribeRequestObject = new SubscribeRequestObject();
        SubscribeRequestObject.SubscribeListObject subscribeListObject =
            new SubscribeRequestObject.SubscribeListObject();
        subscribeRequestObject.setSubscribeListObject(subscribeListObject);

        List<SubscribeRequestObject.Subscribe> subscribeList = new ArrayList<>();

        SubscribeRequestObject.Subscribe subscribe1 = new SubscribeRequestObject.Subscribe();

        String timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());

        String minsec = DateTimeFormatter.ofPattern("mmss").format(LocalDateTime.now());
        //        String subscribeID = "421000001250" + "03" + timestamp + "00001";
        //        subscribe.setSubscribeID("440200000005030000002691704792965");

//        subscribe1.setSubscribeID("44020000000503000000269170479"+minsec);
//        subscribe1.setTitle("vehicle");
//        subscribe1.setSubscribeDetail("13");
//        subscribe1.setResourceURI("42020000005030000093");
//        subscribe1.setApplicantName("system");
//        subscribe1.setApplicantOrg("wuhansjy");
//
//        String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
//        subscribe1.setBeginTime(time);
//        subscribe1.setEndTime("20260606145245");
//        subscribe1.setReceiveAddr("http://11.32.32.62:17676/VIID/SubscribeNotifications");
//        subscribe1.setReportInterval(3);
//        subscribe1.setReason("get_vehicle");
//        subscribe1.setOperateType(0);
//        subscribe1.setSubscribeStatus(0);
//        subscribe1.setResourceClass("4");
//        /**
//         * 返回结果图片约定：
//         * -1 不传图片；01 车辆大图；02 车牌彩色小图；11 人脸图；14 场景图
//         * 对应数据推送时的SubImageInfo对象中的type字段
//         */
//        subscribe1.setResultImageDeclare("1");
//        subscribe1.setResultFeatureDeclare(1);
//        subscribeList.add(subscribe1);

        SubscribeRequestObject.Subscribe subscribe = new SubscribeRequestObject.Subscribe();
//        String  timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());

//        subscribe.setSubscribeID("440200000005030000002691704792967");
        subscribe.setSubscribeID("44020000000503000000269170479"+minsec);
        subscribe.setTitle("face");
        subscribe.setSubscribeDetail("12");
        subscribe.setResourceURI("42020000005030000093");
        subscribe.setApplicantName("system");
        subscribe.setApplicantOrg("wuhansjy");

        String     time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
        subscribe.setBeginTime(time);
        subscribe.setEndTime("20280606145245");
        subscribe.setReceiveAddr("http://11.32.32.62:17676/VIID/SubscribeNotifications");
        subscribe.setReportInterval(3);
        subscribe.setReason("get_face");
        subscribe.setOperateType(0);
        subscribe.setSubscribeStatus(0);
        subscribe.setResourceClass("4");
        subscribe.setResultImageDeclare("11");
//        subscribe.setResultImageDeclare("14");
        subscribe.setResultFeatureDeclare(1);
        subscribeList.add(subscribe);

        subscribeListObject.setSubscribeObject(subscribeList);

        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.parseMediaType("application/VIID+JSON"));
        headers.set("User-Identify", "42020000005030000999");
        log.info("Subscribe headers=========>" + JSONUtil.toJsonStr(headers));
        log.info("Subscribe body=========>" + JSONUtil.toJsonStr(subscribeRequestObject));
        HttpEntity<String> httpEntity = new HttpEntity<>(JSONUtil.toJsonStr(subscribeRequestObject), headers);
        RestTemplate restTemplate = new RestTemplate();
        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
            @Override
            public void handleError(ClientHttpResponse response) throws IOException {
                if (response.getRawStatusCode() != 401) {
                    super.handleError(response);
                }
            }
        });
        ResponseEntity<String> entity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        log.info("Subscribe 应答头部消息" + entity.getHeaders());
        if (org.apache.http.HttpStatus.SC_OK == entity.getStatusCode()
            .value() || org.apache.http.HttpStatus.SC_CREATED == entity.getStatusCode().value()) {
            log.info("消息体：" + entity.getBody());
            log.info("订阅成功");
        } else {
            log.info("消息体:" + entity.getBody());
            log.info("订阅失败");
        }

        return entity;
    }


//    @PutMapping("/VIID/Subscribes/{ID}")
//    public ResponseEntity<ResponseStatusRequestObject> cancelSubscribes(HttpServletRequest request) {
//        try {
//
//            BufferedReader reader = request.getReader();
//            String str = reader.readLine();
//
//            String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
//            // 取消订阅入参
//            SubscribeObjectReq subscribeDTO = JSON.parseObject(str, SubscribeObjectReq.class);
//            if (subscribeDTO != null) {
//                // 响应参数
//                ResponseStatus responseStatusRequestObject = new ResponseStatus();
//                List<ResponseStatusListRequestObject.ResponseStatus> responseStatusesList = new ArrayList<>();
//                String subscribeID = subscribeDTO.getSubscribeObject().getSubscribeID();
//
//                // 删除订阅信息
//                String key = "subscribe_redis::" + subscribeID;
//                boolean del = redisCache.deleteObject(key);
//
//                if (del) {
//                    ResponseStatus.ResponseStatus responseStatus = new ResponseStatusRequestObject.ResponseStatus();
//                    responseStatus.setId(subscribeID);   // 订阅id
//                    responseStatus.setLocalTime(time);
//                    responseStatus.setRequestURL("/VIID/Subscribes/<ID>");
//                    responseStatus.setStatusCode("0");
//                    responseStatus.setStatusString(HttpStatus.OK.getReasonPhrase());
//
//                    responseStatusRequestObject.setResponseStatusObject(responseStatus);
//                    LinkedMultiValueMap<String, String> headers = new LinkedMultiValueMap<>();
//                    headers.add("Content-Type", "application/*+JSON");
//                    ResponseEntity<ResponseStatusRequestObject> responseEntity = new ResponseEntity<>(responseStatusRequestObject, headers, HttpStatus.OK);
//                    return responseEntity;
//                }
//
//
//            }
//        } catch (IOException e) {
//            log.info("/VIID/Subscribes/<ID>异常:", e);
//        }
//        return null;
//    }

    //向已注册的子视图，发送订阅消息，先以订阅人脸类型为例进行测试  URL_SUBSCRIBE
//    @PostMapping("/subscribe/{id}")
//    public Object sendSubscribeMsg(@PathVariable Integer id) throws Exception
//    {
//        //需要传入viid 或者 IP/port/ user/ password
//        //VIIDServer viidServer
//        log.info("viid="+id);
//
//        ResponseStatus status = new ResponseStatus("/VIID/Subscribes", VIIDRespEnum.OK.getCode(), new Date());
//        String url = "http://11.32.32.11:31666"+"/VIID/Subscribes";
//
//        SubscribeRequestObject subscribeRequestObject = new SubscribeRequestObject();
//        SubscribeRequestObject.SubscribeListObject subscribeListObject = new SubscribeRequestObject.SubscribeListObject();
//        subscribeRequestObject.setSubscribeListObject(subscribeListObject);
//
//        List<SubscribeRequestObject.Subscribe> subscribeList = new ArrayList<>();
//
//        SubscribeRequestObject.Subscribe subscribe = new SubscribeRequestObject.Subscribe();
////
//        String timestamp = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
//        //        String subscribeID = "421000001250" + "03" + timestamp + "00001";
////        subscribe.setSubscribeID("440200000005030000002691704792965");
//        subscribe.setSubscribeID("440200000005030000002691704792965");
//        subscribe.setTitle("face");
//        subscribe.setSubscribeDetail("12");
//        subscribe.setResourceURI("42020000005030000093");
//        subscribe.setApplicantName("system");
//        subscribe.setApplicantOrg("wuhansjy");
//
//        String time = DateTimeFormatter.ofPattern("yyyyMMddHHmmss").format(LocalDateTime.now());
//        subscribe.setBeginTime(time);
//        subscribe.setEndTime("20240606145245");
//        subscribe.setReceiveAddr("http://11.32.32.62:17676/VIID/SubscribeNotifications");
//        subscribe.setReportInterval(3);
//        subscribe.setReason("get_face");
//        subscribe.setOperateType(0);
//        subscribe.setSubscribeStatus(0);
//        subscribe.setResourceClass("4");
//        subscribe.setResultImageDeclare("14");
//        subscribe.setResultFeatureDeclare(1);
//
//        subscribeList.add(subscribe);
//        subscribeListObject.setSubscribeObject(subscribeList);
//
//        HttpHeaders headers = new HttpHeaders();
//        headers.setContentType(MediaType.parseMediaType("application/VIID+JSON"));
//        headers.set("User-Identify", "42020000005030000999");
//        log.info("Subscribe headers=========>" + JSONUtil.toJsonStr(headers));
//        log.info("Subscribe body=========>" + JSONUtil.toJsonStr(subscribeRequestObject));
//        HttpEntity<String> httpEntity = new HttpEntity<>(JSONUtil.toJsonStr(subscribeRequestObject), headers);
//        RestTemplate restTemplate = new RestTemplate();
//        restTemplate.setErrorHandler(new DefaultResponseErrorHandler() {
//            @Override
//            public void handleError(ClientHttpResponse response) throws IOException {
//                if (response.getRawStatusCode() != 401) {
//                    super.handleError(response);
//                }
//            }
//        });
//        ResponseEntity<String> entity = restTemplate.exchange(url, HttpMethod.POST, httpEntity,String.class);
//        log.info("Subscribe 应答头部消息" + entity.getHeaders());
//        if (org.apache.http.HttpStatus.SC_OK == entity.getStatusCode().value()) {
//            log.info("消息体：" + entity.getBody());
//            log.info("订阅成功");
//        } else {
//            log.info("消息体:" + entity.getBody());
//            log.info("订阅失败");
//        }
//
//        if (entity != null && entity.getStatusCodeValue() == 401)
//        {
//            HttpHeaders headers2 = entity.getHeaders();
//            List<String> list = headers2.get("WWW-Authenticate");
//
//            String authHeader = list.get(0);
//            Map<String, String> map = getMapByKeyArray(authHeader.replaceAll("Digest ", "").split(","));
//            map.put("username", "42020000005030000093");
//            map.put("uri", Urlconstant.URL_SUBSCRIBE);
//            map.put("cnonce", "0a4f1131");
//            map.put("nc", "00000002");
//            map.put("qop", "auth");
//            map.put("response", getResponse(map, "12345678"));
//
//            String strAuthHeader = buildAuthHeader(map);
//            HttpHeaders head = RestTemplateUtils.setAuthHeader(strAuthHeader);
//            head.set("User-Identify", "42020000005030000999");
//            head.setConnection("keep-alive");
//            HttpEntity<String> requestEntity2 = new HttpEntity<String>(JSONUtil.toJsonStr(subscribeRequestObject),head);
//            log.info("subscribe head =========>"+ JSONUtil.toJsonStr(head));
//            log.info("subscribe Body=========>"+ JSONUtil.toJsonStr(subscribeRequestObject));
//            ResponseEntity<String> responseEntity = restTemplate.exchange(url, HttpMethod.POST, requestEntity2, String.class);
//            log.info("getStatusCode=========>"+ responseEntity.getStatusCode().value());
//            log.info("responseEntity=========>"+ JSONUtil.toJsonStr(responseEntity));
//            if (org.apache.http.HttpStatus.SC_OK == responseEntity.getStatusCode().value())
//            {
//                log.info("Second 消息体"+responseEntity.getBody());
//                log.info("Second 订阅成功");
//            } else {
//                log.info("Second 消息体" + responseEntity.getBody());
//                log.info("Second 订阅失败");
//            }
//        }
//
//        return entity;
//    }


    private String getResponse(Map<String, String> maps, String password) {

        String hA1 = DegistUtils.getMD5(maps.get("username") + ":" + maps.get("realm") + ":" + password);
        String hA2 = DegistUtils.getMD5("POST:" + maps.get("uri"));
        String source = CharSequenceUtil.format("{}:{}:{}:{}:{}:{}",hA1,maps.get("nonce"), maps.get("nc"),
            maps.get("cnonce"),maps.get("qop"),hA2);
        return DegistUtils.getMD5(source);
    }


    private String buildAuthHeader(Map<String, String> maps) {
        StringBuffer value = new StringBuffer();
        value.append("Digest username=\"").append(maps.get("username")).append("\", ").append("realm=\"")
            .append(maps.get("realm")).append("\", ").append("nonce=\"").append(maps.get("nonce")).append("\", ")
            .append("uri=\"").append(maps.get("uri")).append("\", ").append("response=\"")
            .append(maps.get("response")).append("\", ").append("opaque=\"").append(maps.get("opaque"))
            .append("\", ").append("qop=\"").append(maps.get("qop")).append("\", ").append("nc=\"").append(maps.get("nc"))
            .append("\", ").append("cnonce=\"").append(maps.get("cnonce")).append("\"");
        return value.toString();
    }

    public Map<String, String> getMapByKeyArray(String[] resourceStr) {
        Map<String, String> maps = new HashMap<String, String>(8);
        for (String str : resourceStr) {
            if (str.contains("realm")) {
                maps.put("realm", getValueByName(str));
            } else if (str.contains("qop")) {
                maps.put("qop", getValueByName(str));
            } else if (str.contains("nonce")) {
                maps.put("nonce", getValueByName(str));
            } else if (str.contains("opaque")) {
                maps.put("opaque", getValueByName(str));
            }
        }
        return maps;
    }
    public String getValueByName(String resourceStr) {
        return resourceStr.substring(resourceStr.indexOf("\"") + 1, resourceStr.lastIndexOf("\""));
    }
}
